package objects;

import java.util.List;

import media.AudioManager;
import media.Sounds;
import world.BodyID;
import world.WorldContactListener;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input.Keys;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.Texture.TextureFilter;
import com.badlogic.gdx.graphics.g2d.Sprite;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.g2d.tiled.TileAtlas;
import com.badlogic.gdx.graphics.g2d.tiled.TileMapRenderer;
import com.badlogic.gdx.graphics.g2d.tiled.TiledObject;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.physics.box2d.Body;
import com.badlogic.gdx.physics.box2d.BodyDef;
import com.badlogic.gdx.physics.box2d.Box2DDebugRenderer;
import com.badlogic.gdx.physics.box2d.CircleShape;
import com.badlogic.gdx.physics.box2d.Contact;
import com.badlogic.gdx.physics.box2d.FixtureDef;
import com.badlogic.gdx.physics.box2d.Joint;
import com.badlogic.gdx.physics.box2d.JointDef.JointType;
import com.badlogic.gdx.physics.box2d.PolygonShape;
import com.badlogic.gdx.physics.box2d.World;

public class Player extends AbstractObject {

	private boolean jumperFacingRight;
	private OrthographicCamera camera;
	private boolean gameOver;

	public Player( World _world,
			OrthographicCamera _camera) {
		camera = _camera;
		world = _world;
		gameOver = false;
		texture = new Texture(Gdx.files.internal("data/sprites/sprite.png"));
		texture.setFilter(TextureFilter.Linear, TextureFilter.Linear);
		sprite = new Sprite(texture, 0, 0, texture.getWidth(),
				texture.getHeight());
		this.type = BodyDef.BodyType.DynamicBody;
		this.position.set(1.0f,5.0f);
		body = world.createBody(this);

		body.setUserData(BodyID.PLAYER);
		PolygonShape jumperShape = new PolygonShape();
		jumperShape.setAsBox(sprite.getWidth() / (2 * PIXELS_PER_METER),
				sprite.getHeight() / (2 * PIXELS_PER_METER));
		body.setFixedRotation(true);

		FixtureDef playerFixtureDef = new FixtureDef();
		playerFixtureDef.shape = jumperShape;
		playerFixtureDef.density = 1.0f;
		playerFixtureDef.friction = 5.0f;

		body.createFixture(playerFixtureDef);
		jumperShape.dispose();

		System.nanoTime();

	}

	public FixtureDef returnFixDef() {
		return fixtureDef;
	}

	public void movePlayer(boolean moveLeft, boolean moveRight, boolean doJump) {
		if (body.getPosition().y < (0-(sprite.getHeight()+10.0f))/PIXELS_PER_METER) {
			gameOver = true;
		} else {
			boolean canJump = false;
			List<Contact> contactList = world.getContactList();
//			for (int i = 0; i < contactList.size(); i++) {
//				Contact contact = contactList.get(i);
//				if ((contact.getFixtureA().getBody().getUserData() == BodyID.PLAYER && contact
//						.getFixtureB().getBody().getUserData() == BodyID.GROUND)
//						|| (contact.getFixtureA().getBody().getUserData() == BodyID.GROUND && contact
//								.getFixtureB().getBody().getUserData() == BodyID.PLAYER)) {

					if (/*(contact.getWorldManifold().getNormal().y > 0)
							|| */(Math.abs(body.getLinearVelocity().y) < 1e-9))
						canJump = true;
					// if (contact.getWorldManifold().getNormal().x > 0) {
					// moveLeft = false;
					// } else {
					// if (contact.getWorldManifold().getNormal().x < 0) {
					// moveRight = false;
					// }
					// }
//				}

				// if ((contact.getFixtureA().getBody().getUserData() ==
				// BodyID.PLAYER && contact
				// .getFixtureB().getBody().getUserData() == BodyID.BOX)
				// || (contact.getFixtureA().getBody().getUserData() ==
				// BodyID.BOX
				// && contact
				// .getFixtureB().getBody().getUserData() == BodyID.PLAYER)) {
				//
				// System.out.println("box contact");
				//
				// if (contact.getWorldManifold().getNormal().x < 0)
				// System.out.println("box to right");
				//
				// else if (contact.getWorldManifold().getNormal().x > 0)
				// System.out.println("box to left");
				// else if (contact.getWorldManifold().getNormal().y < 0) {
				// System.out.println("box to bottom");
				// canJump = true;
				// moveLeft=true;
				// moveRight=true;
				// } else if (contact.getWorldManifold().getNormal().y > 0)
				// System.out.println("box to top");
				// }
//			}
			// canJump = (Math.abs(body.getLinearVelocity().y) < 1e-9);
			float movementSpeed = canJump ? 0.08f : 0.04f;
			if (moveRight) {
				body.applyLinearImpulse(new Vector2(movementSpeed, 0.0f),
						body.getWorldCenter());
				if (jumperFacingRight == false) {
					sprite.flip(true, false);
				}
				jumperFacingRight = true;
			} else if (moveLeft) {

				body.applyLinearImpulse(new Vector2(-movementSpeed, 0.0f),
						body.getWorldCenter());
				if (jumperFacingRight == true) {
					sprite.flip(true, false);
				}
				jumperFacingRight = false;
			}
			// if (doJump && Math.abs(playerBody.getLinearVelocity().y) < 1e-9)
			// {
			// AudioManager.playSound(Sounds.Jump);
			// playerBody.applyLinearImpulse(new Vector2(0.0f, 0.8f),
			// playerBody.getWorldCenter());
			// System.out.println("jump");
			// }
			// if (doJump && canJump)
			if (doJump && canJump) {
				AudioManager.playSound(Sounds.Jump);
				body.applyLinearImpulse(new Vector2(0.0f, 0.8f),
						body.getWorldCenter());
			}

			Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
			camera.position.x = body.getPosition().x * PIXELS_PER_METER;
			// now = System.nanoTime();
			// if (now - lastRender < 30000000) { // 30 ms, ~33FPS
			// try {
			// Thread.sleep(30 - (now - lastRender) / 1000000);
			// } catch (InterruptedException e) {
			// }
			// }
			//
			// lastRender = now;
		}
	}

	public void renderPlayer(SpriteBatch spriteBatch) {
		spriteBatch.setProjectionMatrix(camera.combined);

		spriteBatch.begin();
		sprite.setPosition(
				(body.getPosition().x * PIXELS_PER_METER) - sprite.getWidth()
						/ 2,
				(body.getPosition().y * PIXELS_PER_METER) - sprite.getHeight()
						/ 2);
		sprite.draw(spriteBatch);
		spriteBatch.end();

	}

	public boolean isGameOver(){
		return gameOver;
	}
	public void setGameOver(boolean _gameOver){
		gameOver = _gameOver;
		
	}
}
